﻿using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using Convertor.Interface;
using Wpf.CommonTools.StaticExtension;
using Wpf.CommonTools.SystemExtension;

namespace Convertor
{
    /// <summary>
    /// ManagePluginControl.xaml 的交互逻辑
    /// </summary>
    public partial class ManagePluginControl : UserControl, IMyWindows, IPluginLog
    {

        public ObservableCollection<Convertor.Interface.IPluginItem> SelectedPlugins
        {
            get { return Config.CurrentPlugin.SelectedPlugins; }
        }

        #region ManagePluginControl Function

        public ManagePluginControl()
        {
            InitializeComponent();
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            //GridLengthConverter leftChange = new GridLengthConverter();
            //double width = Config.GlobalConfig.ManagePluginHorizontalChange;
            //if (width < this.ActualWidth && width > 0)
            //{
            //    GridPlugin.ColumnDefinitions[0].Width = (GridLength)leftChange.ConvertFrom(width);
            //}
        }

        #endregion

        #region TreeView tvPlugins Function

        private void tvPlugins_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                System.Diagnostics.Debug.WriteLine("Delete");
                menuItem_Delete_Click(sender, e);
            }
        }

        private void tvPlugins_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            TreeViewItem treeViewItem = getTreeViewItem(e.OriginalSource as DependencyObject);

            if (treeViewItem != null)
            {
                treeViewItem.Focus();
                e.Handled = false;
            }
        }

        private void tvPlugins_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {

        }

        private void tvPlugins_ContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            var targetData = tvPlugins.SelectedItem;
            if (targetData == null)
            {
                menuItemTConfig.IsEnabled = false;
                menuItemTDelete.IsEnabled = false;
                menuItemTMoveTo.IsEnabled = false;
                menuItemTRunTo.IsEnabled = false;
                menuItemCopy.IsEnabled = false;
            }
            else
            {
                menuItemTConfig.IsEnabled = true;
                menuItemTDelete.IsEnabled = true;
                menuItemTMoveTo.IsEnabled = true;
                menuItemTRunTo.IsEnabled = true;
                menuItemCopy.IsEnabled = true;
            }
            menuItemPaste.IsEnabled = Config.CopiedPlugin != null;
        }

        private void tvPlugins_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            TreeView parent = sender as TreeView;
            PluginItem data = getTreeViewItemClicked((FrameworkElement)e.OriginalSource, parent) as PluginItem;

            if (data != null)
            {
                DragDrop.DoDragDrop(parent, data, DragDropEffects.Move);

                if (e.ClickCount == 2)
                {
                    menuItem_Config_Click(sender, e);
                }
            }
        }

        private void tvPlugins_Drop(object sender, DragEventArgs e)
        {
            TreeView parent = sender as TreeView;
            PluginItem dragData = e.Data.GetData(typeof(PluginItem)) as PluginItem;

            PluginItem targetData = getTreeViewItemClicked((FrameworkElement)e.OriginalSource, parent) as PluginItem;

            var list = targetData == null ? Config.CurrentPlugin.SelectedPlugins : targetData.ChildPlugins;

            int order1 = dragData.Order;
            if (dragData != null)
            {
                if (order1 == -1)
                {
                    list.Add(new PluginItem(dragData.Path, Config.GlobalConfig.AllPlugins[dragData.Path], null) { ParentPlugin = targetData, Order = Config.CurrentPlugin.SelectedPlugins.Count + 1, Config = null });
                }
                else
                {
                    if (targetData == dragData)
                    {
                        return;
                    }
                    var dragParentPluginList = dragData.ParentPlugin == null ? Config.CurrentPlugin.SelectedPlugins : dragData.ParentPlugin.ChildPlugins;
                    bool b = dragParentPluginList.Remove(dragData);
                    if (b)
                    {
                        if (targetData == null)
                        {
                            Config.CurrentPlugin.SelectedPlugins.Add(dragData);
                            dragData.ParentPlugin = null;
                        }
                        else
                        {
                            var targetParentPluginList = targetData.ParentPlugin == null ? Config.CurrentPlugin.SelectedPlugins : targetData.ParentPlugin.ChildPlugins;
                            int order2 = targetParentPluginList.IndexOf(targetData);
                            targetParentPluginList.Insert(order2, dragData);
                            dragData.ParentPlugin = targetData.ParentPlugin;
                        }
                    }
                }
            }
        }

        #endregion

        #region TreeView tvPlugins ContextMenu Function

        private void menuItem_Config_Click(object sender, RoutedEventArgs e)
        {
            IConvertHelper fun = ((IPluginOutputHeler)MyWindows).OutputFunc;
            PluginItem data = tvPlugins.SelectedItem as PluginItem;
            if (data != null)
            {
                if (fun.ParentContent == null)
                {
                    fun.ParentContent = ((MainWindow)MyWindows).InputText;
                }
                LoadConfigWindow config = new LoadConfigWindow(data, Config.GlobalConfig.AllPlugins[data.Path], fun.ParentContent, fun.Convert);
                config.SetCenterOfWindow(MyWindows);
                if (config.ShowDialog() == true)
                {
                }
            }
        }

        private void menuItem_RunTo_Click(object sender, RoutedEventArgs e)
        {
            IConvertHelper fun = ((IPluginOutputHeler)MyWindows).OutputFunc;
            fun.RunToPluginItem = tvPlugins.SelectedItem as PluginItem;
            if (fun.RunToPluginItem != null)
            {
                ((MainWindow)MyWindows).StartOutputThread();
            }
        }

        private void menuItem_MoveTo_Click(object sender, RoutedEventArgs e)
        {
            PluginItem data = tvPlugins.SelectedItem as PluginItem;
            if (data != null)
            {
                MovePluginToWindow mp = new MovePluginToWindow(Config.CurrentPlugin, data);
                mp.SetCenterOfWindow(MyWindows);
                if (mp.ShowDialog() == true)
                {
                }
            }
        }

        private void menuItem_Delete_Click(object sender, RoutedEventArgs e)
        {
            PluginItem data = tvPlugins.SelectedItem as PluginItem;
            if (data != null)
            {
                var parentPluginList = data.ParentPlugin == null ? Config.CurrentPlugin.SelectedPlugins : data.ParentPlugin.ChildPlugins;
                bool b = parentPluginList.Remove(data);
                if (b)
                {
                }
            }
        }

        private void menuItem_Copy_Click(object sender, RoutedEventArgs e)
        {
            PluginItem data = tvPlugins.SelectedItem as PluginItem;
            if (data != null)
            {
                Config.CopiedPlugin = data;
            }
        }

        private void menuItem_Paste_Click(object sender, RoutedEventArgs e)
        {
            if (Config.CopiedPlugin as IPluginItem != null)
            {
                PluginItem item = Config.CopiedPlugin.Clone() as PluginItem;
                item.ParentPlugin = null;
                item.Order = Config.CurrentPlugin.SelectedPlugins.Count + 1;

                Config.CurrentPlugin.SelectedPlugins.Add(item);
                //Config.CopiedPlugin = null;
            }
        }


        private void menuItem_Clear_Click(object sender, RoutedEventArgs e)
        {
            if (MessageBox.Show(UILanguage.FindResource("ReallyClearAllPlugins"), "", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                Config.CurrentPlugin.SelectedPlugins.Clear();
            }
        }

        #endregion

        #region Control Function

        private void lstPlugin_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            ListBox parent = sender as ListBox;
            PluginItem dragData = getObjectDataFromPoint(parent, e.GetPosition(parent)) as PluginItem;

            if (dragData != null)
            {
                DragDrop.DoDragDrop(parent, dragData, DragDropEffects.Move);

                if (e.ClickCount == 1)
                {
                    parent.SelectedItem = dragData;
                }
                if (e.ClickCount == 2)
                {
                    Config.CurrentPlugin.SelectedPlugins.Add(new PluginItem(dragData.Path, Config.GlobalConfig.AllPlugins[dragData.Path], null) { ParentPlugin = null, Order = Config.CurrentPlugin.SelectedPlugins.Count + 1, Config = null });
                }
            }
        }

        private void GridSplitter_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
        {
            Config.GlobalConfig.ManagePluginHorizontalChange = GridPlugin.ColumnDefinitions[0].ActualWidth;
            GridPlugin.RowDefinitions[0].SetBinding(RowDefinition.HeightProperty, new Binding() { Source = Config.GlobalConfig, Path = new PropertyPath("ManagePluginHorizontalChange") });
        }

        #endregion

        #region Private Function

        private object getObjectDataFromPoint(ListBox source, Point point)
        {
            UIElement element = source.InputHitTest(point) as UIElement;
            if (element != null)
            {
                object data = DependencyProperty.UnsetValue;
                while (data == DependencyProperty.UnsetValue)
                {
                    data = source.ItemContainerGenerator.ItemFromContainer(element);
                    if (data == DependencyProperty.UnsetValue)
                        element = VisualTreeHelper.GetParent(element) as UIElement;
                    if (element == source)
                        return null;
                }
                if (data != DependencyProperty.UnsetValue)
                    return data;
            }
            return null;
        }

        private object getTreeViewItemClicked(FrameworkElement sender, TreeView treeView)
        {
            Point p = ((sender as FrameworkElement)).TranslatePoint(new Point(0, 0), treeView);
            DependencyObject obj = treeView.InputHitTest(p) as DependencyObject;
            while (obj != null && !(obj is TreeViewItem))
                obj = VisualTreeHelper.GetParent(obj);
            if (obj == null)
            {
                return null;
            }
            else
            {
                return (obj as TreeViewItem).DataContext;
            }
        }
      
        private static TreeViewItem getTreeViewItem(DependencyObject source)
        {
            while (source != null && !(source is TreeViewItem))
                source = VisualTreeHelper.GetParent(source);

            return source as TreeViewItem;
        }

        #endregion

        #region IMainWindows 成员

        public Window MyWindows { get; set; }

        #endregion

        #region IPluginLog 成员

        public LogDelegate Log { set; private get; }

        #endregion

    }
}
